#include "maincore.h"
#include <QDebug>
#include <QGuiApplication>
#include <QClipboard>
#include "tcp/remoteclient.h"
#include "Screen/normalscreen.h"
#include "Screen/screenwidget.h"
#include <QCryptographicHash>
#include <QMessageBox>

MainCore::MainCore(QObject *parent) : QObject(parent), client(new RemoteClient(this))
{
    connect(client, &RemoteClient::receivedVersion, this, &MainCore::receivedVersion);
    connect(client, &RemoteClient::receivedCreateWindow, this, &MainCore::receivedCreateWindow);
    connect(client, &RemoteClient::receivedCloseWindow, this, &MainCore::receivedCloseWindow);
//    connect(client, &RemoteClient::receivedResizeWindow, this, &MainCore::receivedResizeWindow);
    connect(client, &RemoteClient::receivedFramebuffer, this, &MainCore::receivedFramebuffer);
    connect(client, &RemoteClient::receivedCutText, this, &MainCore::receivedCutText);
    connect(QGuiApplication::clipboard(), &QClipboard::dataChanged, this, &MainCore::on_clipboardChanged);
}

MainCore::~MainCore()
{
    for (QMap<int, ScreenWidget*>::iterator i = m_screenDict.begin(); i!= m_screenDict.end(); i++)
    {
        i.value()->close();
        i.value()->deleteLater();
    }
}

bool MainCore::connectToHost(QHostAddress &address, quint16 port)
{
    client->connectToHost(address, port);
    return client->waitForConnected(-1);
}

void MainCore::receivedVersion(const QByteArray &version)
{
    QByteArray localVersion = client->getVersion();
    if(localVersion!=version)
    {
        qDebug()<<"版本不匹配，连接将断开";
        client->disconnectFromHost();
    }
    qDebug()<<"版本验证成功";
    client->sendVersion();
}

void MainCore::receivedCreateWindow(int id, int width, int height, int codec)
{
    qDebug()<<QString("创建窗口:%1 宽:%2 高:%3 编码类型:%4").arg(id).arg(width).arg(height).arg(codec);
    ScreenWidget *sw = new ScreenWidget(id);
    sw->getScreen()->setScreenSize(width, height, codec);
    connect(sw->getScreen(), &NormalScreen::mouseChanged, this, &MainCore::on_mouseChanged);
    connect(sw->getScreen(), &NormalScreen::keyChanged, this, &MainCore::on_keyChanged);
    connect(sw->getScreen(), &NormalScreen::wheelChanged, this, &MainCore::on_wheelChanged);
    connect(sw, &ScreenWidget::Minimized, this, &MainCore::on_min);
    connect(sw, &ScreenWidget::NotMinimized, this, &MainCore::on_notMin);
    m_screenDict.insert(id, sw);
    sw->showMaximized();
}

void MainCore::receivedCloseWindow(int id)
{
    qDebug()<<QString("关闭窗口:%1").arg(id);
    ScreenWidget *sw = m_screenDict.take(id);
    sw->close();
    sw->deleteLater();
}

void MainCore::receivedFramebuffer(int id,  const QByteArray &data)
{
    if(!m_screenDict.contains(id))
    {
        qCritical()<<QString("未找到%1对应的窗口。").arg(id);
        return;
    }
    ScreenWidget *sw = m_screenDict[id];
    sw->getScreen()->putFramebuffer(data);
}

void MainCore::receivedCutText(const QString &text)
{
     QClipboard *clipboard = QGuiApplication::clipboard();

    QString old = clipboard->text();
    if(old != text)
    {
        clipboard->setText(text);
    }
}

void MainCore::on_disconnected()
{
    QMessageBox::information(nullptr, "信息", "与服务器断开连接");
    QCoreApplication::exit(0);
}

void MainCore::on_mouseChanged(const Qt::MouseButtons& button, bool isPress, const QPoint& point)
{
    NormalScreen* screen = qobject_cast<NormalScreen*>(sender());
    if(!screen)
    {
        return;
    }
    int wid = screen->getId();
    client->sendMouse(wid, button, isPress, point.x(), point.y());
}

void MainCore::on_keyChanged(int key, bool isPress)
{
    NormalScreen* screen = qobject_cast<NormalScreen*>(sender());
    if(!screen)
    {
        return;
    }
    int wid = screen->getId();
    client->sendKey(wid, key, isPress);
}

void MainCore::on_wheelChanged(int delta)
{
    NormalScreen* screen = qobject_cast<NormalScreen*>(sender());
    if(!screen)
    {
        return;
    }
    int wid = screen->getId();
    client->sendWheel(wid, delta);
}

void MainCore::on_min()
{
    qDebug()<<"in min";
    ScreenWidget* sw = qobject_cast<ScreenWidget*>(sender());
    if(!sw)
    {
        return;
    }
    qDebug()<<"send stop";
    client->sendStopCap(sw->getScreen()->getId());
}

void MainCore::on_notMin()
{
    qDebug()<<"in notMin";
    ScreenWidget* sw = qobject_cast<ScreenWidget*>(sender());
    if(!sw)
    {
        return;
    }
    qDebug()<<"send start";
    client->sendStartCap(sw->getScreen()->getId());
}

void MainCore::on_clipboardChanged()
{
    QClipboard *clipboard = QGuiApplication::clipboard();
    QString text = clipboard->text();
    client->sendCutText(text);
}
